#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //testThreadPool();
    //testConCurrent();
    //testMoveToThread();
    //testRun();
    testMesQueue();

}

MainWindow::~MainWindow()
{
    if(m_testThread)
        m_testThread->deleteLater();
    delete ui;
}

void MainWindow::testThreadPool()
{
    qDebug() << "main thread id: " << QThread::currentThreadId();

    int var = 1;
    QThreadPool::globalInstance()->start([&var](){
        qDebug() << "work thread id: " << QThread::currentThreadId();
        while(var < 100) {
            QThread::sleep(1);
            var ++;
        }
    });

    while(var < 100) {
        qDebug() << "var: " << var;
        QThread::sleep(1);
    }
}

void MainWindow::testConCurrent()
{
    qDebug() << "main thread id: " << QThread::currentThreadId();

    int var = 1;
    QtConcurrent::run([&var](){
        qDebug() << "work thread id: " << QThread::currentThreadId();
        while(var < 100) {
            QThread::sleep(1);
            var ++;
        }
    });

    while(var < 100) {
        qDebug() << "var: " << var;
        QThread::sleep(1);
    }
}

void MainWindow::testMoveToThread()
{
    qDebug() << "main thread id: " << QThread::currentThreadId();

    int var = 1;
    std::unique_ptr<QThread> testThread = std::make_unique<QThread>();
    std::unique_ptr<QObject> threadObj(new QObject());
    threadObj.get()->moveToThread(testThread.get());
    connect(testThread.get(), &QThread::started, threadObj.get(), [&var](){
        qDebug() << "work thread id: " << QThread::currentThreadId();
        while(var < 100) {
            QThread::sleep(1);
            var ++;
        }
    });

    testThread->start();
    while(var < 100) {
        qDebug() << "var: " << var;
        QThread::sleep(1);
    }

    testThread->quit();
    testThread->wait();
}

void MainWindow::testRun()
{
    int var = 1;
    m_testThread = std::make_unique<TestThread>();
    m_testThread->setVar(var);
    connect(m_testThread.get(), &TestThread::signalVar, this, [](int var){
        qDebug() << "var: " << var;
        QThread::sleep(1);
    });

    m_testThread->startThread();
}


void MainWindow::testMesQueue()
{
    qDebug() << "main thread id: " << QThread::currentThreadId();
    int var = 1;
    m_workerThread = new QThread(this);
    if(m_worker.get()) {
        m_worker.reset();
        m_workerThread->quit();
        m_workerThread->wait();
    }

    if(!m_worker.get()) {
        m_worker = std::unique_ptr<Worker>(new Worker());
        m_worker->setVar(var);
        connect(m_worker.get(), &Worker::signalVar, this, \
            [](int var) {
                qDebug() << "var: " << var;
                QThread::sleep(10);
                }, Qt::QueuedConnection);
    }

    m_worker->moveToThread(m_workerThread);
    connect(m_workerThread, &QThread::finished, m_worker.get(), &QObject::deleteLater);
    m_workerThread->start();

    // 调用
    QMetaObject::invokeMethod(m_worker.get(), "onPrintVar", \
        Qt::QueuedConnection, QGenericArgument());

}

